#include "include/dtu_common.h"
#include "include/dtu_memory.h"
#include "include/dtu_log.h"
#include "include/dtu_config.h"
#include "include/dtu_network.h"
#include "include/dtu_web.h"
#include "include/dtu_at_command.h"
#include "include/dtu_modbus.h"
#include "include/dtu_data_collect.h"
#include "include/dtu_data_push.h"
#include "include/dtu_mqtt.h"

#include <signal.h>
#include <sys/stat.h>

/* 全局变量定义 */
device_info_t g_device_info = {0};
system_status_t g_system_status = {0};

/* 静态变量 */
static bool g_running = true;
static bool g_test_mode = false;
static bool g_daemon_mode = false;
static char g_config_file[512] = {0};
static pthread_t g_main_thread;

/* 函数声明 */
static void signal_handler(int sig);
static dtu_error_t init_device_info(void);
static dtu_error_t init_system_modules(void);
static void cleanup_system_modules(void);
static void* main_loop(void* arg);
static void print_banner(void);
static void print_usage(const char* program_name);
static dtu_error_t parse_command_line(int argc, char* argv[]);
static void data_collect_callback(const collect_result_t* result, void* user_data);

/**
 * @brief 信号处理函数
 */
static void signal_handler(int sig)
{
    switch (sig) {
        case SIGINT:
        case SIGTERM:
            DTU_LOG_INFO("Received signal %d, shutting down...", sig);
            g_running = false;
            break;
        case SIGHUP:
            DTU_LOG_INFO("Received SIGHUP, reloading configuration...");
            dtu_config_reload();
            break;
        default:
            DTU_LOG_WARN("Received unknown signal %d", sig);
            break;
    }
}

/**
 * @brief 初始化设备信息
 */
static dtu_error_t init_device_info(void)
{
    /* 设置设备基本信息 */
    DTU_STRNCPY(g_device_info.device_id, "DTU001", sizeof(g_device_info.device_id));
    DTU_STRNCPY(g_device_info.serial_number, "SN20240101001", sizeof(g_device_info.serial_number));
    DTU_STRNCPY(g_device_info.firmware_version, DTU_VERSION_STRING, sizeof(g_device_info.firmware_version));
    DTU_STRNCPY(g_device_info.hardware_version, "HW1.0", sizeof(g_device_info.hardware_version));

    /* 根据编译选项确定设备型号 */
#ifdef DTU_BUILD_WIFI_ETHERNET
    g_device_info.model = DTU_MODEL_WIFI_ETHERNET;
#elif defined(DTU_BUILD_4G_ETHERNET)
    g_device_info.model = DTU_MODEL_4G_ETHERNET;
#else
    g_device_info.model = DTU_MODEL_ETHERNET_ONLY;
#endif

    g_device_info.manufacture_date = time(NULL);

    /* 初始化系统状态 */
    g_system_status.system_running = true;
    g_system_status.uptime = time(NULL);

    for (int i = 0; i < 3; i++) {
        g_system_status.network_status[i] = NETWORK_STATUS_DISCONNECTED;
    }

    DTU_LOG_INFO("Device initialized: ID=%s, Model=%d, SN=%s",
                 g_device_info.device_id, g_device_info.model, g_device_info.serial_number);

    return DTU_OK;
}

/**
 * @brief 初始化系统模块
 */
static dtu_error_t init_system_modules(void)
{
    dtu_error_t ret;

    /* 初始化内存管理器 */
    ret = dtu_memory_init();
    if (ret != DTU_OK) {
        fprintf(stderr, "Failed to initialize memory manager: %s\n", dtu_error_string(ret));
        return ret;
    }

    /* 初始化日志系统 - 仅使用控制台输出 */
    log_config_t log_config = {
        .level = LOG_LEVEL_INFO,
        .output_mask = LOG_OUTPUT_CONSOLE,
        .log_file = "",
        .max_file_size = 0,
        .max_backup_files = 0,
        .enable_color = true,
        .enable_timestamp = true,
        .enable_thread_id = false,
        .enable_function_name = true
    };
    ret = dtu_log_init(&log_config);
    if (ret != DTU_OK) {
        fprintf(stderr, "Failed to initialize log system: %s\n", dtu_error_string(ret));
        return ret;
    }

    DTU_LOG_INFO("DTU system starting up...");

    /* 初始化配置管理器 */
    const char* config_file = (g_config_file[0] != '\0') ? g_config_file : NULL;
    ret = dtu_config_init(config_file);
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to initialize config manager: %s", dtu_error_string(ret));
        return ret;
    }

    /* 加载配置文件 */
    ret = dtu_config_load();
    if (ret != DTU_OK) {
        DTU_LOG_WARN("Failed to load config file, using defaults: %s", dtu_error_string(ret));
        /* 使用默认配置继续运行 */
    }

    /* 初始化网络管理器 - 错误不阻塞主程序 */
    ret = dtu_network_init(g_device_info.model);
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to initialize network manager: %s (continuing anyway)", dtu_error_string(ret));
        /* 不返回错误，继续启动其他服务 */
    } else {
        DTU_LOG_INFO("Network manager initialized successfully");

        /* 启动网络监控 */
        ret = dtu_network_start_monitor();
        if (ret != DTU_OK) {
            DTU_LOG_ERROR("Failed to start network monitor: %s (continuing anyway)", dtu_error_string(ret));
        } else {
            DTU_LOG_INFO("Network monitor started successfully");
        }
    }

    /* 初始化Web服务器 */
    ret = dtu_web_init(NULL);
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to initialize web server: %s", dtu_error_string(ret));
        return ret;
    }

    /* 启动Web服务器 */
    ret = dtu_web_start();
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to start web server: %s", dtu_error_string(ret));
        return ret;
    }

    /* 初始化AT命令系统 - 错误不阻塞主程序 */
    ret = dtu_at_init();
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Failed to initialize AT command system: %s (continuing anyway)", dtu_error_string(ret));
        /* 不返回错误，继续启动其他服务 */
    } else {
        DTU_LOG_INFO("AT command system initialized successfully");
    }

    /* 初始化数据采集模块 */
    const dtu_config_t* config = dtu_config_get();
    if (config) {
        ret = dtu_data_collect_init(&config->collect_config, &config->rs485_config, &config->rs232_config);
        if (ret != DTU_OK) {
            DTU_LOG_ERROR("Failed to initialize data collection: %s", dtu_error_string(ret));
            return ret;
        }

        /* 加载Modbus设备配置到数据采集模块 - 使用新的AT+POLLSTR格式 */
        for (int i = 0; i < 16; i++) {
            if (strlen(config->modbus_config.pollstr_commands[i]) == 0) {
                continue; /* 跳过未配置的设备 */
            }

            /* 解析AT+POLLSTR指令字符串 */
            int serial_id = 1; /* 默认使用RS485 */
            int device_id, enable, crc_enable;
            char poll_string[256] = {0};
            char temp_poll_string[256] = {0};

            /* 先尝试新格式带引号的格式 */
            if (sscanf(config->modbus_config.pollstr_commands[i],
                      "AT+POLLSTR=%d,%d,%d,%d,\"%255[^\"]\"",
                      &serial_id, &device_id, &enable, &crc_enable, temp_poll_string) == 5) {
                DTU_STRNCPY(poll_string, temp_poll_string, sizeof(poll_string));
            }
            /* 再尝试新格式不带引号的格式 */
            else if (sscanf(config->modbus_config.pollstr_commands[i],
                           "AT+POLLSTR=%d,%d,%d,%d,%255s",
                           &serial_id, &device_id, &enable, &crc_enable, temp_poll_string) == 5) {
                DTU_STRNCPY(poll_string, temp_poll_string, sizeof(poll_string));
            }
            /* 兼容旧格式带引号 */
            else if (sscanf(config->modbus_config.pollstr_commands[i],
                           "AT+POLLSTR=%d,%d,%d,\"%255[^\"]\"",
                           &device_id, &enable, &crc_enable, temp_poll_string) == 4) {
                DTU_STRNCPY(poll_string, temp_poll_string, sizeof(poll_string));
                serial_id = 1; /* 旧格式默认使用RS485 */
            }
            /* 兼容旧格式不带引号 */
            else if (sscanf(config->modbus_config.pollstr_commands[i],
                           "AT+POLLSTR=%d,%d,%d,%255s",
                           &device_id, &enable, &crc_enable, temp_poll_string) == 4) {
                DTU_STRNCPY(poll_string, temp_poll_string, sizeof(poll_string));
                serial_id = 1; /* 旧格式默认使用RS485 */
            } else {
                DTU_LOG_ERROR("Failed to parse AT+POLLSTR command: %s",
                             config->modbus_config.pollstr_commands[i]);
                continue;
            }

            if (enable == 0) {
                DTU_LOG_DEBUG("Device %d is disabled, skipping", device_id);
                continue; /* 跳过禁用的设备 */
            }

            /* 转换为数据采集设备配置 */
            device_config_t device_config = {0};
            snprintf(device_config.name, sizeof(device_config.name), "设备%d", device_id);
            snprintf(device_config.description, sizeof(device_config.description),
                    "Modbus设备%d (串口%s, 轮询字符串: %s)", device_id,
                    (serial_id == 1) ? "RS485" : "RS232", poll_string);
            device_config.slave_id = device_id;
            device_config.serial_id = serial_id;
            device_config.timeout = 1000;  /* 默认超时1秒 */
            device_config.retry_count = 3; /* 默认重试3次 */
            device_config.enabled = true;
            DTU_STRNCPY(device_config.poll_string, poll_string, sizeof(device_config.poll_string));
            device_config.crc_enable = (crc_enable == 1);
            device_config.points = NULL;   /* 暂时不设置数据点 */
            device_config.point_count = 0;

            ret = dtu_data_collect_add_device(&device_config);
            if (ret != DTU_OK) {
                DTU_LOG_ERROR("Failed to add device %s to data collection: %s",
                            device_config.name, dtu_error_string(ret));
            } else {
                DTU_LOG_INFO("Added device %s (ID: %d, serial: %s, poll_string: %s) to data collection",
                           device_config.name, device_id, (serial_id == 1) ? "RS485" : "RS232", poll_string);
            }
        }

        /* 设置数据采集回调 */
        dtu_data_collect_set_callback(data_collect_callback, NULL);

        /* 根据配置决定是否启动数据采集 - 错误不阻塞主程序 */
        if (config->collect_config.auto_collect) {
            DTU_LOG_INFO("Auto collect enabled, starting data collection");
            ret = dtu_data_collect_start();
            if (ret != DTU_OK) {
                DTU_LOG_ERROR("Failed to start data collection: %s (continuing anyway)", dtu_error_string(ret));
                /* 不返回错误，继续启动其他服务 */
            } else {
                if (g_test_mode) {
                    DTU_LOG_INFO("Test mode: Data collection started (may fail due to hardware limitations)");
                } else {
                    DTU_LOG_INFO("Data collection started successfully");
                }
            }
        } else {
            DTU_LOG_INFO("Auto collect disabled, data collection not started");
        }

        /* 初始化数据推送模块 */
        push_config_t push_config = {
                .protocol = config->push_config.protocol,
                .format = DATA_FORMAT_JSON,
                .server_port = config->push_config.server_port,
                .timeout = config->push_config.timeout,
                .retry_count = config->push_config.retry_count,
                .retry_interval = config->push_config.retry_interval,
                .enable_ssl = config->push_config.enable_ssl,
                .enable_compression = config->push_config.enable_compression,
                .keepalive = config->push_config.keepalive,
                .clean_session = config->push_config.clean_session
        };
        DTU_STRNCPY(push_config.server_host, config->push_config.server_host, sizeof(push_config.server_host));
        DTU_STRNCPY(push_config.username, config->push_config.username, sizeof(push_config.username));
        DTU_STRNCPY(push_config.password, config->push_config.password, sizeof(push_config.password));
        DTU_STRNCPY(push_config.topic, config->push_config.topic, sizeof(push_config.topic));
        DTU_STRNCPY(push_config.client_id, config->push_config.client_id, sizeof(push_config.client_id));

        ret = dtu_data_push_init(&push_config);
        if (ret != DTU_OK) {
            DTU_LOG_ERROR("Failed to initialize data push: %s", dtu_error_string(ret));
            return ret;
        }

        /* 启动数据推送服务 - 错误不阻塞主程序 */
        ret = dtu_data_push_start();
        if (ret != DTU_OK) {
            DTU_LOG_ERROR("Failed to start data push service: %s (continuing anyway)", dtu_error_string(ret));
            /* 不返回错误，继续启动其他服务 */
        } else {
            if (g_test_mode) {
                DTU_LOG_INFO("Test mode: Data push service started (may have network limitations)");
            } else {
                DTU_LOG_INFO("Data push service started successfully");
            }
        }
    }

    DTU_LOG_INFO("All system modules initialized successfully");
    return DTU_OK;
}

/**
 * @brief 清理系统模块
 */
static void cleanup_system_modules(void)
{
    DTU_LOG_INFO("Shutting down system modules...");

    /* 停止并清理数据推送服务 */
    dtu_data_push_stop();
    dtu_data_push_cleanup();

    /* 停止并清理数据采集模块 */
    dtu_data_collect_stop();
    dtu_data_collect_cleanup();

    /* 清理AT命令系统 */
    dtu_at_cleanup();

    /* 停止并清理Web服务器 */
    dtu_web_stop();
    dtu_web_cleanup();

    /* 停止网络监控并清理网络管理器 */
    dtu_network_stop_monitor();
    dtu_network_cleanup();

    /* 保存配置并清理配置管理器 */
    dtu_config_save();
    dtu_config_cleanup();

    /* 清理日志系统 */
    DTU_LOG_INFO("DTU system shutdown completed");
    dtu_log_cleanup();

    /* 检查内存泄漏并清理内存管理器 */
    uint32_t leaks = dtu_memory_check_leaks();
    if (leaks > 0) {
        printf("Warning: %u memory leaks detected\n", leaks);
        dtu_memory_print_leaks();
    }
    dtu_memory_cleanup();
}

/**
 * @brief 主循环线程
 */
static void* main_loop(void* arg)
{
    (void)arg;

    DTU_LOG_INFO("Main loop started");

    while (g_running) {
        /* 更新系统状态 */
        g_system_status.uptime = time(NULL) - g_system_status.uptime;

        /* 检查网络状态 */
        for (int i = 0; i < 3; i++) {
            g_system_status.network_status[i] = dtu_network_check_status((network_type_t)i);
        }

        /* 执行周期性任务 */
        /* TODO: 添加数据采集、推送等任务 */

        /* 休眠1秒 */
        sleep(1);
    }

    DTU_LOG_INFO("Main loop stopped");
    return NULL;
}

/**
 * @brief 打印程序横幅
 */
static void print_banner(void)
{
    printf("\n");
    printf("========================================\n");
    printf("    DTU (Data Transfer Unit) v%s\n", DTU_VERSION_STRING);
    printf("    Industrial IoT Gateway Solution\n");
    printf("========================================\n");
    printf("Device Model: ");
    switch (g_device_info.model) {
        case DTU_MODEL_ETHERNET_ONLY:
            printf("Ethernet Only\n");
            break;
        case DTU_MODEL_WIFI_ETHERNET:
            printf("WiFi + Ethernet\n");
            break;
        case DTU_MODEL_4G_ETHERNET:
            printf("4G + Ethernet\n");
            break;
        default:
            printf("Unknown\n");
            break;
    }
    printf("Device ID: %s\n", g_device_info.device_id);
    printf("Serial Number: %s\n", g_device_info.serial_number);
    printf("Firmware Version: %s\n", g_device_info.firmware_version);
    printf("Hardware Version: %s\n", g_device_info.hardware_version);
    printf("========================================\n\n");
}

/**
 * @brief 打印使用说明
 */
static void print_usage(const char* program_name)
{
    printf("Usage: %s [OPTIONS]\n", program_name);
    printf("\nOptions:\n");
    printf("  -h, --help           Show this help message\n");
    printf("  -v, --version        Show version information\n");
    printf("  -c, --config FILE    Specify configuration file\n");
    printf("  -d, --daemon         Run as daemon\n");
    printf("  -l, --log-level LEVEL Set log level (DEBUG|INFO|WARN|ERROR|FATAL)\n");
    printf("  -p, --port PORT      Set web server port (default: %d)\n", DTU_WEB_PORT);
    printf("  --reset-config       Reset to default configuration\n");
    printf("  --test-mode          Run in test mode\n");
    printf("\nExamples:\n");
    printf("  %s                   Run with default settings\n", program_name);
    printf("  %s -d -c /etc/dtu.conf Run as daemon with custom config\n", program_name);
    printf("  %s --reset-config    Reset configuration to defaults\n", program_name);
    printf("\n");
}

/**
 * @brief 解析命令行参数
 */
static dtu_error_t parse_command_line(int argc, char* argv[])
{
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            print_usage(argv[0]);
            exit(0);
        } else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
            printf("DTU version %s\n", DTU_VERSION_STRING);
            exit(0);
        } else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0) {
            if (i + 1 >= argc) {
                fprintf(stderr, "Error: Missing configuration file argument\n");
                return DTU_ERROR_INVALID_PARAM;
            }
            DTU_STRNCPY(g_config_file, argv[i + 1], sizeof(g_config_file));
            i++;
        } else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--daemon") == 0) {
            g_daemon_mode = true;
        } else if (strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--log-level") == 0) {
            if (i + 1 >= argc) {
                fprintf(stderr, "Error: Missing log level argument\n");
                return DTU_ERROR_INVALID_PARAM;
            }
            /* TODO: 设置日志级别 */
            i++;
        } else if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--port") == 0) {
            if (i + 1 >= argc) {
                fprintf(stderr, "Error: Missing port argument\n");
                return DTU_ERROR_INVALID_PARAM;
            }
            /* TODO: 设置Web服务器端口 */
            i++;
        } else if (strcmp(argv[i], "--reset-config") == 0) {
            /* TODO: 重置配置 */
            printf("Configuration reset not implemented yet\n");
        } else if (strcmp(argv[i], "--test-mode") == 0) {
            g_test_mode = true;
            printf("Test mode enabled - will skip hardware initialization\n");
        } else {
            fprintf(stderr, "Error: Unknown option '%s'\n", argv[i]);
            print_usage(argv[0]);
            return DTU_ERROR_INVALID_PARAM;
        }
    }

    return DTU_OK;
}

/**
 * @brief 主函数
 */
int main(int argc, char* argv[])
{
    dtu_error_t ret;

    /* 解析命令行参数 */
    ret = parse_command_line(argc, argv);
    if (ret != DTU_OK) {
        return EXIT_FAILURE;
    }

    /* 初始化设备信息 */
    ret = init_device_info();
    if (ret != DTU_OK) {
        fprintf(stderr, "Failed to initialize device info: %s\n", dtu_error_string(ret));
        return EXIT_FAILURE;
    }

    /* 打印程序横幅 */
    print_banner();

    /* 设置信号处理 */
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGHUP, signal_handler);
    signal(SIGPIPE, SIG_IGN);

    /* 初始化系统模块 */
    ret = init_system_modules();
    if (ret != DTU_OK) {
        fprintf(stderr, "Failed to initialize system modules: %s\n", dtu_error_string(ret));
        cleanup_system_modules();
        return EXIT_FAILURE;
    }

    /* 创建主循环线程 */
    if (pthread_create(&g_main_thread, NULL, main_loop, NULL) != 0) {
        DTU_LOG_ERROR("Failed to create main loop thread");
        cleanup_system_modules();
        return EXIT_FAILURE;
    }

    DTU_LOG_INFO("DTU system started successfully");
    printf("DTU system is running. Press Ctrl+C to stop.\n");
    printf("Web interface available at: http://localhost:%d\n", DTU_WEB_PORT);

    /* 等待主循环线程结束 */
    pthread_join(g_main_thread, NULL);

    /* 清理系统模块 */
    cleanup_system_modules();

    printf("DTU system stopped.\n");
    return EXIT_SUCCESS;
}

/* 实现通用函数 */
const char* dtu_error_string(dtu_error_t error)
{
    switch (error) {
        case DTU_OK: return "Success";
        case DTU_ERROR: return "General error";
        case DTU_ERROR_INVALID_PARAM: return "Invalid parameter";
        case DTU_ERROR_MEMORY: return "Memory error";
        case DTU_ERROR_NETWORK: return "Network error";
        case DTU_ERROR_TIMEOUT: return "Timeout";
        case DTU_ERROR_NOT_FOUND: return "Not found";
        case DTU_ERROR_PERMISSION: return "Permission denied";
        case DTU_ERROR_BUSY: return "Resource busy";
        case DTU_ERROR_NOT_SUPPORTED: return "Not supported";
        default: return "Unknown error";
    }
}

const char* dtu_network_type_string(network_type_t type)
{
    switch (type) {
        case NETWORK_TYPE_ETHERNET: return "Ethernet";
        case NETWORK_TYPE_WIFI: return "WiFi";
        case NETWORK_TYPE_4G: return "4G";
        default: return "Unknown";
    }
}

const char* dtu_network_status_string(network_status_t status)
{
    switch (status) {
        case NETWORK_STATUS_DISCONNECTED: return "Disconnected";
        case NETWORK_STATUS_CONNECTING: return "Connecting";
        case NETWORK_STATUS_CONNECTED: return "Connected";
        case NETWORK_STATUS_ERROR: return "Error";
        default: return "Unknown";
    }
}



/**
 * @brief 数据采集回调函数
 */
static void data_collect_callback(const collect_result_t* result, void* user_data)
{
    (void)user_data;

    if (!result) {
        DTU_LOG_WARN("Data collect callback called with NULL result");
        return;
    }

    /* 推送采集到的数据 */
    dtu_error_t ret = dtu_data_push_data(result, false);
    if (ret != DTU_OK) {
        DTU_LOG_ERROR("Push failed for %s: %s", result->device_name, dtu_error_string(ret));
    }
}
